package repo

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"time"
)

const defaultTimeout = 50 * time.Second

type Response struct {
	Code int64
	Msg  string
	Data struct {
		RelativePath string
	}
}

// 短连接
var client = http.Client{Timeout: defaultTimeout, Transport: &http.Transport{DialContext: (&net.Dialer{
	Timeout: 1 * time.Second, // 连接超时
}).DialContext, DisableKeepAlives: true}}

func Upload(path string, url string, token string) (string, error) {
	// 打开文件
	file, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 创建一个缓冲区来存储 multipart 数据
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	// 创建一个 form 文件字段
	part, err := writer.CreateFormFile("file", filepath.Base(file.Name()))
	if err != nil {
		return "", err
	}

	// 将文件内容复制到 form 文件字段
	_, err = io.Copy(part, file)
	if err != nil {
		return "", err
	}
	// 关闭 multipart writer 以写入结尾边界
	err = writer.Close()
	if err != nil {
		return "", err
	}

	// 创建 HTTP 请求
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return "", err
	}

	// 设置 Content-Type 头
	req.Header.Set("Content-Type", writer.FormDataContentType())
	req.Header.Set("Authorization", "Bearer "+token)

	// 发送 HTTP 请求
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("upload stauts [%d]", resp.StatusCode)
	}
	// 读取响应
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	var response Response
	if err = json.Unmarshal(respBody, &response); err != nil {
		return "", err
	}
	if response.Code != 0 {
		return "", fmt.Errorf("upload response code[%d],msg[%s]", response.Code, response.Msg)
	}
	return response.Data.RelativePath, nil
}
